// ignore_for_file: deprecated_member_use_from_same_package

part of '../test.dart';

/// 默认创建的用户信息
const String phone = "15900780010";
const int idTest = 1;

/// 在测试中，method和url都不再重要，因为他们的本质是为了路由
/// 而测试中绕过了shelf的路由机制
Request testRequest({
  String router = "/",
  String method = "GET",
  dynamic body,
  Map<String, String>? headers,
  String? token,
}) {
  headers ??= {};
  if (token != null) headers["Authorization"] = token;

  return Request(
    method,
    // url并不重要，因为单元测试时已经绕过了路由机制
    // 这里后面需要加/，否则shelf会报错
    Uri.parse("http://localhost$router"),
    body: stringify(body),
    headers: headers,
  );
}

// 测试时自动填写token
late String testToken;
Request tokenRequest({
  String router = "/",
  String method = "GET",
  dynamic body,
  Map<String, String>? headers,
}) =>
    testRequest(
        router: router,
        method: method,
        body: body,
        headers: headers,
        token: testToken);

/// 初始化一个测试用的服务器，在测试前像保姆一样把所有事情做好，只需要调用argConn就可以了
/// 测试结束后，自动完成清扫工作
void prepareAndCleanPostgres(String name) {
  // 在测试开始前，初始化这个名字的数据库
  setUpAll(() async => await initConnection(ArgPostgres.local(), name));

  // 在每个测试开始前，创建所有商业表格以及创建一个新用户
  setUp(() async {
    await createBusinessTables();
    // 添加一个默认用户
    await userTable.create({"phone": phone});
  });

  /// 在每个测试后会清空整个数据库，以方便下次测试
  tearDown(() async => await argConn.value.tableDeleteAll());

  // 所有测试结束后，关闭连接并删除此数据库
  tearDownAll(() async {
    await argConn.value.close();
    await DatabaseKit.delete(name);
  });
}

Matcher isPostgresBug = throwsA(isA<ServerException>());

/// 获取测试用的token，此操作需要服务器和User table已经创建，因为它会自动创建一个合法的用户
Future<void> getTestToken() async {
  // 首先创建一个验证码，并获取验证码
  final sendSmsHandler = pipelineGeneral.addHandler(sendSms);
  final sendSmsRequest = testRequest(body: {"phone": phone});
  final response = await sendSmsHandler(sendSmsRequest);
  final String code = await response.readAsString();
  // 如果将正确的验证码填上，就发现是200，并且得到了一个token
  final handler = pipelineGeneral.addHandler(redeemSms);
  final request2 = testRequest(body: {"phone": phone, "code": code});
  final response2 = await handler(request2);
  final token = await response2.readAsString();
  // 解码token后，可以得到用户id为1（自增id）
  final subject = TokenKit.redeem(token);
  assert(subject == "1");
  // 将token赋值给全局的测试token
  testToken = token;
}
